import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;


public class RadiusProtocolDecoder extends CumulativeProtocolDecoder {

	@Override
	protected boolean doDecode(IoSession session, IoBuffer buffer, ProtocolDecoderOutput out) throws Exception {
		RadiusPacket radiusPacket = new RadiusPacket();

		System.out.println("start decoding");
		
		while (buffer.hasRemaining()) {
            int packetLength = buffer.limit();
            if(packetLength < RadiusPacket.MIN_PACKET_LENGTH) {
            	return false;
            }
            if (packetLength > RadiusPacket.MAX_PACKET_LENGTH) {
            	return false;
            }
            
    		int commandCode = buffer.get();
    		int identifier = buffer.get();
    		int length = buffer.getUnsignedShort();            
    		byte[] auth = new byte[16];
    		buffer.get(auth);
    		
    		radiusPacket.setCommandCode(commandCode);
    		radiusPacket.setIdentifier(identifier);
    		radiusPacket.setLength(packetLength);
    		radiusPacket.setAuth(auth);
    		
    		while (buffer.position() < packetLength) {
    			int avpCode = buffer.get();
    			int avpLength = buffer.get();
    			byte[] avpValue = new byte[avpLength - 2]; // subtracting first two bytes from avp byte array which don't belong to avp value array 
    			buffer.get(avpValue);
    			RadiusAttribute attr = new RadiusAttribute(avpCode, avpValue, avpLength);
    			radiusPacket.addRadiusAttribute(attr);
    		}
    		
    		out.write(radiusPacket);
		}
		
		/*
		if (currentLength < RadiusPacket.MIN_PACKET_LENGTH) {
			//TODO: log this
			return false; //not enough data in buffer to start processing the packet
		}
		
		if (currentLength > RadiusPacket.MAX_PACKET_LENGTH) {
			//TODO: log this
			return false; // too many data in buffer (???)
		}
		*/
		

		/*
		int packetIdentifier = buffer.get();
		int packetLength = buffer.getUnsignedShort();
		
		if (packetLength < RadiusPacket.MIN_PACKET_LENGTH || currentLength < packetLength) {
			return false;
		}

		*/
		System.out.println("end decoding");
		
		return true;
	}
}
